import io from 'socket.io-client';
import { TextUtil } from '@/contrib/utils';
import { recordError } from '@/exception/error-handle';
import createDebug from '@/contrib/debug';
import { PartialKeys } from '../contrib/types';

const debug = createDebug('worker:websocket');

interface Config {
  url: string;
  opts?: SocketIOClient.ConnectOpts;
  bizConfig: {
    /** 登录后的用户id */
    uid: string;
  }
}

const DEFAULT_CONFIG = {
  url: import.meta.env.VITE_API,
  opts: {
    transports: ['websocket', 'polling'],
  },
};

export type msgType = 'connect' | 'new_msg' | 'vip_expired' | 'update_user_info';

export default class SocketIO {
  socket?: SocketIOClient.Socket;

  config: Config;

  correctEnv = false;

  constructor(public parentConfig: PartialKeys<Config, keyof typeof DEFAULT_CONFIG>) {
    this.config = {
      ...DEFAULT_CONFIG,
      ...parentConfig,
    };
    this.connect();
    this.errorHandler();
  }

  connect() {
    // 因为获取环境变量是异步的，这里只能用户主动连接，无法在构造实例时自动connect，自动connect会导致用户的on
    this.socket = io(this.config.url, this.config.opts);
    this.socket.on('connect', () => {
      debug('连接成功');
      this.emit('login', this.config.bizConfig.uid);
    });
  }

  disconnect() {
    debug('disconnect');
    this.socket?.disconnect();
  }

  on<T = Object>(eventName: msgType, cb: (data: T) => void) {
    // cb(new TextUtil().parse('{&quot;cust_id&quot;:12988,&quot;type&quot;:1,&quot;title&quot;:&quot;反馈回复&quot;,&quot;content&quot;:&quot;111111&quot;,&quot;created_time&quot;:&quot;2023-12-12 15:53:48&quot;,&quot;id&quot;:18}'))
    this.socket?.on(eventName, (data: string) => {
      debug('received message', eventName, data);
      const formatedData = new TextUtil().parse<T>(data);
      cb(formatedData);
    });
  }

  emit<T>(eventName: string, data: T) {
    this.socket?.emit(eventName, data);
  }

  errorHandler() {
    this.socket?.on('connect_error', (err: Error) => {
      debug('连接错误', err);
      recordError(err);
    });
  }
}
